/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.modules.system.service.impl;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.RequiredArgsConstructor;
import me.zhengjie.config.exception.WeChatException;
import me.zhengjie.constant.ConstantUtils;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.*;
import me.zhengjie.modules.system.repository.DisChannelMemberRepository;
import me.zhengjie.modules.system.service.DisChannelMemberService;
import me.zhengjie.modules.system.service.DisPartnerService;
import me.zhengjie.modules.system.service.WxUserService;
import me.zhengjie.modules.system.service.dto.DisChannelMemberDto;
import me.zhengjie.modules.system.service.dto.DisChannelMemberQueryCriteria;
import me.zhengjie.modules.system.service.mapstruct.DisChannelMemberMapper;
import me.zhengjie.modules.web.service.mybatisplus.IDisChannelMemberPlusService;
import me.zhengjie.modules.web.service.mybatisplus.IDisChannelPlusService;
import me.zhengjie.modules.web.service.mybatisplus.IDisPartnerPlusService;
import me.zhengjie.modules.web.service.mybatisplus.IDisPartnerUserPlusService;
import me.zhengjie.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @author wangyu
 * @website https://el-admin.vip
 * @description 服务实现
 * @date 2024-03-17
 **/
@Service
@RequiredArgsConstructor
public class DisChannelMemberServiceImpl implements DisChannelMemberService {

    private final DisChannelMemberRepository disChannelMemberRepository;
    private final DisChannelMemberMapper disChannelMemberMapper;

    @Autowired
    private IDisChannelMemberPlusService memberPlusService;

    @Autowired
    private IDisChannelPlusService channelPlusService;

    @Autowired
    private WxUserService wxUserService;

    @Autowired
    DisPartnerService disPartnerService;

    @Autowired
    private IDisPartnerPlusService disPartnerPlusService;

    @Autowired
    private IDisPartnerUserPlusService disPartnerUserPlusService;

    @Override
    public Map<String, Object> queryAll(DisChannelMemberQueryCriteria criteria, Pageable pageable) {
        Page<DisChannelMember> page = disChannelMemberRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        Map<String, Object> dataMap = PageUtil.toPage(page.map(disChannelMemberMapper::toDto));
        if (MapUtil.isEmpty(dataMap) || Objects.isNull(dataMap.get("content"))) {
            return null;
        }

        List<DisChannelMemberDto> content = (List<DisChannelMemberDto>) dataMap.get("content");
        if (CollectionUtils.isEmpty(content)) {
            return null;
        }
        String channelCode = content.get(0).getChannelCode();
        LambdaQueryWrapper<DisChannel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DisChannel::getChannelCode, channelCode);
        List<DisChannel> list = channelPlusService.list(wrapper);
        String adminName = "";
        if (CollectionUtils.isNotEmpty(list)) {
            adminName = list.get(0).getAdminName();
        }
        for (DisChannelMemberDto disChannelMemberDto : content) {
            disChannelMemberDto.setAdminName(adminName);
            WxUser wxUser = wxUserService.findByOpenId(disChannelMemberDto.getMemberOpenid());
            if (Objects.isNull(wxUser)) {
                continue;
            }
            disChannelMemberDto.setIdentityName(wxUser.getIdentityName());
            if (StringUtils.isBlank(wxUser.getIdentityName())) {
                String identityName = disPartnerService.getIdentityName(disChannelMemberDto.getMemberMobile());
                disChannelMemberDto.setIdentityName(identityName);
            }
        }
        return dataMap;
    }

    @Override
    public List<DisChannelMemberDto> queryAll(DisChannelMemberQueryCriteria criteria) {
        return disChannelMemberMapper.toDto(disChannelMemberRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public DisChannelMemberDto findById(Long channelMemberId) {
        DisChannelMember disChannelMember = disChannelMemberRepository.findById(channelMemberId).orElseGet(DisChannelMember::new);
        ValidationUtil.isNull(disChannelMember.getChannelMemberId(), "DisChannelMember", "channelMemberId", channelMemberId);
        return disChannelMemberMapper.toDto(disChannelMember);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DisChannelMemberDto create(DisChannelMember resources) {
        if (StringUtils.isAnyBlank(resources.getChannelCode(), resources.getMemberOpenid(), resources.getMemberMobile())) {
            throw new BadRequestException("缺少参数");
        }
        LambdaQueryWrapper<DisChannelMember> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DisChannelMember::getMemberOpenid, resources.getMemberOpenid());
        List<DisChannelMember> list = memberPlusService.list(wrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            String channelCode = list.get(0).getChannelCode();
            LambdaQueryWrapper<DisChannel> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(DisChannel::getChannelCode, channelCode);
            List<DisChannel> list1 = channelPlusService.list(wrapper1);
            throw new BadRequestException("已被添加到【" + list1.get(0).getChannelName() + "】,先解除才能被添加");
        }
        return disChannelMemberMapper.toDto(disChannelMemberRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(DisChannelMember resources) {
        if (StringUtils.isAnyBlank(resources.getChannelCode(), resources.getMemberOpenid(), resources.getMemberMobile())) {
            throw new WeChatException("缺少参数");
        }
        DisChannelMember disChannelMember = disChannelMemberRepository.findById(resources.getChannelMemberId()).orElseGet(DisChannelMember::new);
        ValidationUtil.isNull(disChannelMember.getChannelMemberId(), "DisChannelMember", "id", resources.getChannelMemberId());
        disChannelMember.copy(resources);

        LambdaQueryWrapper<DisChannelMember> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DisChannelMember::getMemberOpenid, resources.getMemberOpenid());
        wrapper.ne(DisChannelMember::getChannelCode, resources.getChannelCode());
        List<DisChannelMember> list = memberPlusService.list(wrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            String channelCode = list.get(0).getChannelCode();
            LambdaQueryWrapper<DisChannel> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(DisChannel::getChannelCode, channelCode);
            List<DisChannel> list1 = channelPlusService.list(wrapper1);
            throw new WeChatException("已被添加到【" + list1.get(0).getChannelName() + "】,先解除才能被添加");
        }
        disChannelMemberRepository.save(disChannelMember);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long channelMemberId : ids) {
            disChannelMemberRepository.deleteById(channelMemberId);
        }
    }

    @Override
    public void download(List<DisChannelMemberDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (DisChannelMemberDto disChannelMember : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("手机号", disChannelMember.getMemberMobile());
            map.put("真实姓名", disChannelMember.getMemberName());
            map.put("昵称", disChannelMember.getMemberNickname());
            map.put("身份名称", disChannelMember.getIdentityName());
            map.put("渠道编码", disChannelMember.getChannelCode());
            map.put("创建时间", disChannelMember.getCreateTime());
            map.put("更新时间", disChannelMember.getUpdateTime());
            map.put("创建人", disChannelMember.getCreateby());
            map.put("更新人", disChannelMember.getUpdateby());
            map.put("状态", disChannelMember.getChannelMemberStatus());
            map.put("管理员openid", disChannelMember.getMemberOpenid());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public Map<String, Object> queryAllChannel(DisChannelMemberQueryCriteria criteria, Pageable pageable) {
        Map<String, Object> finalMap = new HashMap<String, Object>() {{
            put("content", new ArrayList<>());
            put("totalElements", 0);
        }};
        LambdaQueryWrapper<DisChannel> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(DisChannel::getAdminMobile, SecurityUtils.getCurrentUserMobile());
        List<DisChannel> channelList = channelPlusService.list(wrapper1);
        if (CollectionUtils.isEmpty(channelList)) {
            //如果渠道没有查询到则查合伙人
            return queryPartner();
        }
        DisChannel disChannel = channelList.get(0);
        criteria.setChannelCode(disChannel.getChannelCode());

        Page<DisChannelMember> page = disChannelMemberRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        Map<String, Object> dataMap = PageUtil.toPage(page.map(disChannelMemberMapper::toDto));
        if (MapUtil.isEmpty(dataMap) || Objects.isNull(dataMap.get("content"))) {
            return finalMap;
        }

        List<DisChannelMemberDto> content = (List<DisChannelMemberDto>) dataMap.get("content");
        if (CollectionUtils.isEmpty(content)){
            return finalMap;
        }
        String channelCode = content.get(0).getChannelCode();
        LambdaQueryWrapper<DisChannel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DisChannel::getChannelCode, channelCode);
        List<DisChannel> list = channelPlusService.list(wrapper);
        String adminName = "";
        if (CollectionUtils.isNotEmpty(list)) {
            adminName = list.get(0).getAdminName();
        }
        List<DisChannelMemberDto> partnerMemberList = new ArrayList<>();
        for (DisChannelMemberDto disChannelMemberDto : content) {
            disChannelMemberDto.setAdminName(adminName);
            WxUser wxUser = wxUserService.findByOpenId(disChannelMemberDto.getMemberOpenid());
            if (Objects.isNull(wxUser)) {
                continue;
            }
            disChannelMemberDto.setIdentityName(wxUser.getIdentityName());
            if (StringUtils.isBlank(wxUser.getIdentityName())) {
                disChannelMemberDto.setIdentityName(wxUser.getPartnerName());
            }
            //判断是否是合伙人管理员
            LambdaQueryWrapper<DisPartner> partnerWrapper = new LambdaQueryWrapper<>();
            partnerWrapper.eq(DisPartner::getMobile, disChannelMemberDto.getMemberMobile());
            List<DisPartner> partnerList = disPartnerPlusService.list(partnerWrapper);
            if (CollectionUtils.isEmpty(partnerList)){
                continue;
            }
            LambdaQueryWrapper<DisPartnerUser> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(DisPartnerUser::getPartnerId, partnerList.get(0).getPartnerId());
            List<DisPartnerUser> userList = disPartnerUserPlusService.list(userWrapper);
            if (CollectionUtils.isEmpty(userList)) {
                continue;
            }
            for (DisPartnerUser disPartnerUser : userList) {
                DisChannelMemberDto memberDto = new DisChannelMemberDto();
                memberDto.setIdentityName(partnerList.get(0).getPartnerName());
                memberDto.setMemberName(disPartnerUser.getRealName());
                memberDto.setMemberMobile(disPartnerUser.getMobile());
                memberDto.setMemberNickname(StringUtils.defaultIfBlank(disPartnerUser.getNickName(), "无"));
                memberDto.setMemberOpenid(disPartnerUser.getOpenId());
                partnerMemberList.add(memberDto);
            }
        }
        if (CollectionUtils.isNotEmpty(partnerMemberList)){
            List<DisChannelMemberDto> modifiableList = new ArrayList<>(content); // 使用可变列表替换固定大小的列表
            modifiableList.addAll(partnerMemberList);
            dataMap.put("totalElements", modifiableList.size());
            dataMap.put("content", modifiableList);
        }
        return dataMap;
    }

    @Override
    public ChannelMemberCheckResp check(String openId, String channelCode) {
        ChannelMemberCheckResp resp = new ChannelMemberCheckResp();
        LambdaQueryWrapper<DisChannelMember> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DisChannelMember::getMemberOpenid, openId);
        List<DisChannelMember> list = memberPlusService.list(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            resp.setMessage("未绑定可以添加");
            return resp;
        } else {
            resp.setCode(-1);
            String code = list.get(0).getChannelCode();
            LambdaQueryWrapper<DisChannel> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(DisChannel::getChannelCode, code);
            List<DisChannel> list1 = channelPlusService.list(wrapper1);
            if (CollectionUtils.isEmpty(list1)){
                LambdaQueryWrapper<DisChannelMember> wrapper2 = new LambdaQueryWrapper<>();
                wrapper2.eq(DisChannelMember::getMemberOpenid,openId);
                wrapper2.eq(DisChannelMember::getChannelCode,code);
                boolean remove = memberPlusService.remove(wrapper2);
                if (!remove){
                    throw new BadRequestException("系统异常请联系管理员");
                }
                resp.setMessage("未绑定可以添加");
                resp.setCode(0);
                return resp;
            }
            resp.setMessage("已被添加到【" + list1.get(0).getChannelName() + "】,先解除才能被添加");
            return resp;
        }
    }

    private Map<String, Object> queryPartner() {
        Map<String, Object> finalMap = new HashMap<String, Object>() {{
            put("content", new ArrayList<>());
            put("totalElements", 0);
        }};
        LambdaQueryWrapper<DisPartner> wrapper = new LambdaQueryWrapper<>();
        //wrapper.eq(DisPartner::getPartnerStatus, ConstantUtils.Valid);
        wrapper.eq(DisPartner::getMobile, SecurityUtils.getCurrentUserMobile());
        List<DisPartner> list = disPartnerPlusService.list(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            return finalMap;
        }
        DisPartner disPartner = list.get(0);
        LambdaQueryWrapper<DisPartnerUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(DisPartnerUser::getPartnerId, disPartner.getPartnerId());
        List<DisPartnerUser> userList = disPartnerUserPlusService.list(userWrapper);
        if (CollectionUtils.isEmpty(userList)) {
            return finalMap;
        }
        List<DisChannelMemberDto> returnList = new ArrayList<>();
        for (DisPartnerUser disPartnerUser : userList) {
            DisChannelMemberDto memberDto = new DisChannelMemberDto();
            memberDto.setIdentityName(disPartner.getPartnerName());
            memberDto.setMemberName(disPartnerUser.getRealName());
            memberDto.setMemberMobile(disPartnerUser.getMobile());
            memberDto.setMemberNickname(StringUtils.defaultIfBlank(disPartnerUser.getNickName(), "无"));
            memberDto.setMemberOpenid(disPartnerUser.getOpenId());
            returnList.add(memberDto);
        }
        finalMap.put("content", returnList);
        finalMap.put("totalElements", returnList.size());
        return finalMap;
    }
}